﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UtilZ.Dotnet.Ex.Communication.Net.MQBase
{
    /// <summary>
    /// MQ key-value 映射类型消息
    /// </summary>
    public class MQMapMessage : MQMessageAbs, IEnumerable<KeyValuePair<string, object>>, IEnumerable
    {
        private readonly object _monitor = new object();
        private Dictionary<string, MQMapItem> _values = new Dictionary<string, MQMapItem>();

        /// <summary>
        /// 构造函数
        /// </summary>
        public MQMapMessage()
            : base(MQMessageType.Map)
        {

        }

        private void PrimitiveAdd(string key, object value)
        {
            lock (this._monitor)
            {
                if (this._values.ContainsKey(key))
                {
                    throw new ArgumentException($"已存在Key:{key}的属性");
                }

                this._values.Add(key, new MQMapItem(key, value));
            }
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, bool value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, byte value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, byte[] value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, char value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, double value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, short value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, int value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, long value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, object value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, float value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        public void Add(string key, string value)
        {
            this.PrimitiveAdd(key, value);
        }

        /// <summary>
        /// 清空值
        /// </summary>
        public void Clear()
        {
            lock (this._monitor)
            {
                this._values.Clear();
            }
        }

        /// <summary>
        /// 判断是否包含指定的key[包含返回true;不包含返回false]
        /// </summary>
        /// <param name="key">指定的key</param>
        /// <returns>包含返回true;不包含返回false</returns>
        public bool ContainsKey(string key)
        {
            lock (this._monitor)
            {
                return this._values.ContainsKey(key);
            }
        }

        /// <summary>
        /// 移除指定key对应的项[移除返回true;否则返回false]
        /// </summary>
        /// <param name="key">指定key</param>
        /// <returns>移除返回true;否则返回false</returns>
        public bool Remove(string key)
        {
            lock (this._monitor)
            {
                return (this._values.ContainsKey(key) && this._values.Remove(key));
            }
        }

        /// <summary>
        /// 获取项数
        /// </summary>
        public int Count
        {
            get
            {
                lock (this._monitor)
                {
                    return this._values.Count;
                }
            }
        }

        /// <summary>
        /// 判断是否是只读的
        /// </summary>
        public bool IsReadOnly
        {
            get { return false; }
        }

        /// <summary>
        /// 获取或设置值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object this[string key]
        {
            get
            {
                lock (this._monitor)
                {
                    return this._values[key].Value;
                }
            }
            set
            {
                lock (this._monitor)
                {
                    if (this._values.ContainsKey(key))
                    {
                        this._values[key] = new MQMapItem(key, value);
                    }
                    else
                    {
                        this._values.Add(key, new MQMapItem(key, value));
                    }
                }
            }
        }

        /// <summary>
        /// 获取key集合
        /// </summary>
        public ICollection<string> Keys
        {
            get
            {
                lock (this._monitor)
                {
                    return this._values.Keys;
                }
            }
        }

        /// <summary>
        /// 获取value集合
        /// </summary>
        public ICollection<object> Values
        {
            get
            {
                lock (this._monitor)
                {
                    return (from tmpItem in this._values.Values select tmpItem.Value).ToList<object>();
                }
            }
        }



        /// <summary>
        /// 返回一个可遍历的枚举器
        /// </summary>
        /// <returns>可遍历的枚举器</returns>
        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
        {
            List<KeyValuePair<string, object>> list;
            lock (this._monitor)
            {
                list = (from tmpItem in this._values select new KeyValuePair<string, object>(tmpItem.Key, tmpItem.Value.Value)).ToList<KeyValuePair<string, object>>();
            }
            return list.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }


        /// <summary>
        /// 消息体
        /// </summary>
        public override object Body
        {
            get { return _values; }
            set { _values = (Dictionary<string, MQMapItem>)value; }
        }


        /// <summary>
        /// 重写ToString
        /// </summary>
        /// <returns>String</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var kv in this._values)
            {
                sb.Append("Key:");
                sb.Append(kv.Key);
                sb.Append("     Value:");
                sb.Append(kv.Value);
                sb.AppendLine();
            }

            return sb.ToString();
        }
    }
}
